Skip to content

fix(ai): hold every scheduled repair-auto run to its granted hosts - #683

Merged
fclairamb merged 5 commits into
mainfrom
security/scan-specs-2026-10-26
Oct 26, 2026
Merged

fclairamb merged 5 commits into
mainfrom
security/scan-specs-2026-10-26

Conversation

@fclairamb

@fclairamb fclairamb commented Oct 26, 2026 •

Copy link
Copy Markdown
Owner

Specs filed from the daily security scans, and the fix for the one still open.

What changed

  • U1 (low): specs/done/2026/10/2026-10-26-02-ai-repair-hold-skips-param-only-secrets.md. Every scheduled run of a repair: auto version is now held to its granted hosts, whether its credentials sit in secrets or come from a ${param:…} / ${env:…} reference. Before, a check with no secrets value ran unheld with the resolved value. Tests cover the checker, the worker claim path and the agent path, each with a positive control. Docs updated. Batch gate green (make build-backend lint-back test).

Decided by autopilot

  • Nothing: the spec had no open questions.

Earlier scan specs (implemented, in specs/done/2026/10/)

  • S1 (medium): 2026-10-25-01-ai-repair-grant-dropped-by-reference-resolution.md. The repair grant was compared after ${…} references were resolved. Fixed in fix(ai): hold the repair: auto host grant when the script or env holds a reference #678; see U1 for a remaining gap.
  • R1 (medium): 2026-10-24-01-ai-repair-auto-apply-partial-runtime-host.md. repair: auto applied a candidate that kept a literal host and added one built at runtime. Fixed in feat(ai): hold auto-applied repairs to the previous version's hosts (+ scan specs) #663.
  • Q1 (medium): 2026-10-23-02-ai-loop-secret-relay-through-model.md. AI loops relayed an encoded secret through the model.
  • P1 (medium): 2026-10-22-01-ai-script-secret-host-guard-runtime.md. AI runs with real secrets were only host-checked by regex.
  • K1 (medium): 2026-10-20-01-sender-response-body-caps.md. Notification senders and RabbitMQ read responses uncapped.
  • J1 (medium): 2026-10-19-01-a2a-response-size-cap.md. A2A responses were read uncapped.
  • I1 (low): 2026-10-18-01-plugin-schema-file-ref.md. Plugin schema $ref could load local files.
  • G1/G2 (low): 2026-10-17-01-postgres-check-connection-config.md. Postgres conninfo escaping and fallback to the worker's PG* env.
  • F1: 2026-10-16-15-pat-cache-revocation.md. The PAT cache outlived revocation.
  • E1: 2026-10-16-14-totp-on-federated-sign-in.md. No TOTP on federated sign-in.
  • E2: 2026-10-16-13-atomic-auth-attempt-counters.md. Auth attempt counters were not atomic.
  • H3: 2026-10-16-12-mcp-tokens-rejected-on-rest.md. MCP OAuth tokens worked on REST.
  • H2: 2026-10-16-11-slack-signature-fail-closed.md. Slack signature check failed open.
  • T1 / M2 (high): 2026-10-16-10-discovery-scans-egress-guard.md. Discovery scans were outside the egress policy.
  • N4: 2026-10-16-09-js-check-nested-docker-guard.md. A JS docker sub-check bypassed the gate.
  • N3 (high): 2026-10-16-08-status-page-components-cross-org.md. Status-page components could be edited across orgs.
  • D2/D3 (high): 2026-10-16-07-guard-status-subscriber-and-publication-webhooks.md. Subscriber and publication webhooks were not guarded.
  • C3: 2026-10-16-06-accept-invite-existing-account.md. Accepting an invite logged in as an existing account.
  • C1: 2026-10-16-05-kubeconfig-exec-and-incluster.md. Kubeconfig exec and inCluster were allowed.
  • N2: 2026-10-16-04-mysql-dsn-injection.md. MySQL DSN injection.
  • N1: 2026-10-16-03-env-secret-reference-allowlist.md. No allowlist for ${env:} references.
  • C2/H1: 2026-10-16-02-token-purpose-separation.md. Purpose tokens were accepted as access tokens.
  • D1: 2026-10-16-01-microsoft-signin-unverified-email-linking.md. Microsoft nOAuth email linking.

🤖 Generated with Claude Code

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@codecov

codecov Bot commented Oct 26, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 89.71%. Comparing base (958683d) to head (ce6f8e4).

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #683      +/-   ##
==========================================
- Coverage   89.74%   89.71%   -0.04%     
==========================================
  Files        1292     1292              
  Lines      131722   131717       -5     
==========================================
- Hits       118218   118174      -44     
- Misses      13495    13534      +39     
  Partials        9        9              
Files with missing lines Coverage Δ
server/internal/checkers/checkjs/checker.go 91.81% <100.00%> (-0.10%) ⬇️

... and 19 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

fclairamb and others added 4 commits October 26, 2026 08:44
…or not

A granted js check whose token came from a ${param:} or ${env:} reference
in env, with no secrets value, ran on schedule unheld: the hold required a
non-empty secrets map. Execute now installs the repair allowlist on every
run of a granted config. The AI loop keeps its own list.

Spec: specs/todos/2026-10-26-02-ai-repair-hold-skips-param-only-secrets.md

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…hose secrets come from param/env references

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@fclairamb fclairamb changed the title chore(specs): security scan findings fix(ai): hold every scheduled repair-auto run to its granted hosts Oct 26, 2026
@fclairamb
fclairamb merged commit ae9d0ef into main Oct 26, 2026
35 checks passed
@fclairamb
fclairamb deleted the security/scan-specs-2026-10-26 branch October 26, 2026 13:25
fclairamb added a commit that referenced this pull request Oct 26, 2026
🤖 I have created a release *beep* *boop*
---


##
[0.42.0](v0.41.0...v0.42.0)
(2026-10-26)


### Features

* **ai:** hold auto-applied repairs to the previous version's hosts (+
scan specs) ([#663](#663))
([37966e2](37966e2))
* **api:** cursors on the events and incidents APIs
([#640](#640))
([bbd32b9](bbd32b9))
* **auth:** ask the default admin for a real email on first login
([#673](#673))
([e92e608](e92e608))
* **checks:** offer to resolve open incidents when a check is disabled
([#648](#648))
([9553cdc](9553cdc))
* **dash0:** locate e2e and showcase elements by data-testid, with lint
rules ([#672](#672))
([1aceb52](1aceb52))
* **mcp:** bound tool string inputs and disclose side effects
([#644](#644))
([22039c7](22039c7))
* **notifications:** ntfy notifications link to the incident
([#639](#639))
([e466060](e466060))


### Bug Fixes

* **ai:** hold AI loops to the check's hosts after a real-secrets run
([#646](#646))
([7cf836d](7cf836d))
* **ai:** hold every scheduled repair-auto run to its granted hosts
([#683](#683))
([ae9d0ef](ae9d0ef))
* **ai:** hold the repair: auto host grant when the script or env holds
a reference ([#678](#678))
([de4e718](de4e718))
* **auth:** redirect provider logins with an unknown org to the login
page instead of raw JSON
([#676](#676))
([6c4b4fd](6c4b4fd))
* custom-domain status assets, CSS sample, incident header, check scroll
([#689](#689))
([cdd89e0](cdd89e0))
* dashboard down count, mobile event log, browser retry, async report
test send ([#680](#680))
([f53c99b](f53c99b))
* **deps:** update github.com/dop251/goja digest to 1622cea
([#654](#654))
([70d3bfb](70d3bfb))
* **deps:** update github.com/dop251/goja digest to 2921f52
([#685](#685))
([8186068](8186068))
* **deps:** update github.com/dop251/goja digest to 2a9269b
([#668](#668))
([e536f52](e536f52))
* **deps:** update github.com/dop251/goja digest to 3c7039f
([#651](#651))
([bd93ee7](bd93ee7))
* **deps:** update github.com/dop251/goja digest to 6ace4dd
([#652](#652))
([0d7366c](0d7366c))
* **deps:** update github.com/dop251/goja digest to 6b6a90e
([#687](#687))
([4774086](4774086))
* **deps:** update go dependencies (non-major)
([#638](#638))
([b8453fb](b8453fb))
* **deps:** update go dependencies (non-major)
([#649](#649))
([296ecdf](296ecdf))
* **deps:** update go dependencies (non-major)
([#656](#656))
([9aef341](9aef341))
* **deps:** update module github.com/clickhouse/clickhouse-go/v2 to
v2.50.0 ([#688](#688))
([dbced61](dbced61))
* **deps:** update module github.com/gosnmp/gosnmp to v1.47.0
([#659](#659))
([575e17f](575e17f))
* **deps:** update module github.com/oapi-codegen/oapi-codegen/v2 to
v2.8.1 ([#661](#661))
([aa91cb6](aa91cb6))
* **deps:** update module github.com/ohler55/ojg to v1.28.8
([#675](#675))
([5666052](5666052))
* **deps:** update module github.com/posthog/posthog-go to v1.36.2
([#650](#650))
([fb01ef8](fb01ef8))
* **jobs:** retry a due job promptly when its claim rolls back
([#674](#674))
([f0edadd](f0edadd))
* **log:** drop error=&lt;nil&gt; from successful HTTP request logs
([#664](#664))
([4579f59](4579f59))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

---------

Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
fclairamb added a commit that referenced this pull request Oct 27, 2026
…#693)

Specs filed from the daily security scans. Each spec is the tracker for
its finding. This PR adds the specs and implements them.

## What changed

- **V1**: the device consent page now shows when the request was opened,
the requester's IP and client, the approver's IP and a "different
network" hint, a warning above Approve, and a required "I started this
sign-in myself" checkbox when the code arrived pre-filled in the URL.
The approver gets an email after approving. New migration `031_v0_43_0`
stores the requester IP and user agent.
- **W1**: `DELETE /auth/2fa` spends the shared per-user 2FA budget (5
per 15 minutes) before comparing the code, answers 429 `RATE_LIMITED`,
and resets on success. The dash0 dialog shows the message, and no longer
refreshes and retries on a wrong code.
- Batch gate green: backend build, lint and tests, dash0 typecheck and
lint, Playwright 980 passed, 15 skipped.

## Decided by autopilot

- V1, pre-filled code needs a second confirmation?: checkbox only, no
retyping (spec's recommended answer).

## Specs (now implemented, archived in `specs/done/2026/10/`)

- **V1 (medium)**:
`specs/done/2026/10/2026-10-27-01-device-consent-phishing-guard.md`. The
device-flow consent page approves a code anyone can mint without an
account and send by link, already filled in. It shows no warning to
approve only a sign-in you started yourself, and no detail about who
opened the request. One click from a signed-in member gives the
requester a 90-day PAT with the member's role. The fix adds the
requester's details, a warning and an email notification, and keeps the
CLI flow one click.
- **W1 (low)**:
`specs/done/2026/10/2026-10-27-02-disable-2fa-attempt-throttle.md`.
`DELETE /auth/2fa` checks the TOTP code without the per-user attempt
budget that login 2FA uses. Someone holding a stolen session or PAT can
guess the code at the global request rate and remove the second factor
for good. The fix spends the shared 2FA budget before comparing.

## Earlier scan specs (implemented, in `specs/done/2026/10/`)

- **U1 (low)**:
`2026-10-26-02-ai-repair-hold-skips-param-only-secrets.md`. The `repair:
auto` hold applied only when the check's `secrets` map had a value.
Fixed in #683.
- **S1 (medium)**:
`2026-10-25-01-ai-repair-grant-dropped-by-reference-resolution.md`. The
repair grant was compared after `${…}` references were resolved. Fixed
in #678; U1 closed the remaining gap.
- **R1 (medium)**:
`2026-10-24-01-ai-repair-auto-apply-partial-runtime-host.md`. `repair:
auto` applied a candidate that kept a literal host and added one built
at runtime. Fixed in #663.
- **Q1 (medium)**:
`2026-10-23-02-ai-loop-secret-relay-through-model.md`. AI loops relayed
an encoded secret through the model.
- **P1 (medium)**:
`2026-10-22-01-ai-script-secret-host-guard-runtime.md`. AI runs with
real secrets were only host-checked by regex.
- **K1 (medium)**: `2026-10-20-01-sender-response-body-caps.md`.
Notification senders and RabbitMQ read responses uncapped.
- **J1 (medium)**: `2026-10-19-01-a2a-response-size-cap.md`. A2A
responses were read uncapped.
- **I1 (low)**: `2026-10-18-01-plugin-schema-file-ref.md`. Plugin schema
`$ref` could load local files.
- **G1/G2 (low)**: `2026-10-17-01-postgres-check-connection-config.md`.
Postgres conninfo escaping and fallback to the worker's `PG*` env.
- **F1**: `2026-10-16-15-pat-cache-revocation.md`. The PAT cache
outlived revocation.
- **E1**: `2026-10-16-14-totp-on-federated-sign-in.md`. No TOTP on
federated sign-in.
- **E2**: `2026-10-16-13-atomic-auth-attempt-counters.md`. Auth attempt
counters were not atomic.
- **H3**: `2026-10-16-12-mcp-tokens-rejected-on-rest.md`. MCP OAuth
tokens worked on REST.
- **H2**: `2026-10-16-11-slack-signature-fail-closed.md`. Slack
signature check failed open.
- **T1 / M2 (high)**: `2026-10-16-10-discovery-scans-egress-guard.md`.
Discovery scans were outside the egress policy.
- **N4**: `2026-10-16-09-js-check-nested-docker-guard.md`. A JS `docker`
sub-check bypassed the gate.
- **N3 (high)**: `2026-10-16-08-status-page-components-cross-org.md`.
Status-page components could be edited across orgs.
- **D2/D3 (high)**:
`2026-10-16-07-guard-status-subscriber-and-publication-webhooks.md`.
Subscriber and publication webhooks were not guarded.
- **C3**: `2026-10-16-06-accept-invite-existing-account.md`. Accepting
an invite logged in as an existing account.
- **C1**: `2026-10-16-05-kubeconfig-exec-and-incluster.md`. Kubeconfig
`exec` and `inCluster` were allowed.
- **N2**: `2026-10-16-04-mysql-dsn-injection.md`. MySQL DSN injection.
- **N1**: `2026-10-16-03-env-secret-reference-allowlist.md`. No
allowlist for `${env:}` references.
- **C2/H1**: `2026-10-16-02-token-purpose-separation.md`. Purpose tokens
were accepted as access tokens.
- **D1**: `2026-10-16-01-microsoft-signin-unverified-email-linking.md`.
Microsoft nOAuth email linking.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant